/*
 * Copyright 2017 JessYan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package me.jessyan.lifecyclemodel;

import me.jessyan.lifecyclemodel.base.BaseFraction;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.LifecycleObserver;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.ability.fraction.FractionManager;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @hide 此类为实现 {@link LifecycleModel} 的核心类
 * <p>
 */
public class HolderFraction extends BaseFraction {

    private final HiLogLabel lable = new HiLogLabel(HiLog.LOG_APP, 0x00201, "HolderFraction");
    private static final String LOG_TAG = "LifecycleModelStores";

    private static final HolderFractionManager HOLDER_FRACTION_MANAGER = new HolderFractionManager();

    public static final String HOLDER_TAG = "me.jessyan.lifecyclemodel.state.StateProviderHolderFraction";

    private LifecycleModelStore mLifecycleModelStore = new LifecycleModelStore();

    /**
     * 布局
     **/
    @Override
    public int getUIContent() {
        return ResourceTable.Layout_fraction_base;
    }

    @Override
    public void initComponent() {

    }

    private LifecycleObserver mAbilityCallbacks = new LifecycleObserver() {
        /**退出时调用**/
        @Override
        public void onStop() {
            super.onStop();
            HolderFraction fraction = HOLDER_FRACTION_MANAGER.mNotCommittedAbilityHolders.remove(getFractionAbility());
            if (fraction != null) {
                HiLog.error(lable, LOG_TAG, "Failed to save a LifecycleModel for " + getFractionAbility());
            }
        }
    };

    /**
     * 初始化
     **/
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        HOLDER_FRACTION_MANAGER.holderFractionCreated(this); //初始化内部类
    }

    /**
     * 系统将进行销毁，触发此回调函数
     **/
    @Override
    public void onStop() {
        super.onStop();
        mLifecycleModelStore.clear();
    }

    /**
     * 声明方法
     **/
    public LifecycleModelStore getLifecycleModelStore() {
        return mLifecycleModelStore;
    }

    public static HolderFraction holderFractionFor(FractionAbility fability, int i) {
        return HOLDER_FRACTION_MANAGER.holderFractionFor(fability, i);
    }

    @SuppressWarnings("WeakerAccess")
    static class HolderFractionManager {
        private Map<Ability, HolderFraction> mNotCommittedAbilityHolders = new HashMap<>();
        private boolean mAbilityCallbacksIsAdded = false;

        //通过 HOLDER_TAG 找到我们的 Fraction
        HolderFraction holderFractionCreated(HolderFraction holderFraction) {
            FractionAbility parentAbility = holderFraction.getFractionAbility();
            //remove掉mAbilityCallbacks的生命周期
            parentAbility.getLifecycle().removeObserver(holderFraction.mAbilityCallbacks);
            mNotCommittedAbilityHolders.remove(holderFraction.getFractionAbility());//移除 KEY
            return null;
        }

        private HolderFraction findHolderFraction(FractionManager manager) throws IllegalStateException {
            if (manager == null) {
                throw new IllegalStateException("Can't access LifecycleModels from onDestroy");
            }

            Optional<Fraction> fractionByTag = manager.getFractionByTag(HOLDER_TAG);
            if (fractionByTag.isPresent() && !(fractionByTag.get() instanceof HolderFraction)) {
                throw new IllegalStateException("Unexpected "
                        + "fraction instance was returned by HOLDER_TAG");
            }

            return null;
        }

        //创建 Fraction 携带 HOLDER_TAG ，提交
        private HolderFraction createHolderFraction(FractionManager fractionManager, int i) {
            HolderFraction holder = new HolderFraction();
            fractionManager.startFractionScheduler().add(i, holder, HOLDER_TAG).submit();
            return holder;
        }

        //通过 FractionAbility 找到我们的 记录的 Fraction
        HolderFraction holderFractionFor(FractionAbility zability, int i) {
            FractionManager fm = zability.getFractionManager();//找到Fraction
            HolderFraction holder = findHolderFraction(fm);
            if (holder != null) {
                return holder;
            }
            holder = mNotCommittedAbilityHolders.get(zability);//看看列表有没有 Fraction
            if (holder != null) {
                return holder;
            }
            holder = createHolderFraction(fm, i);//创建 （带TAG）
            if (!mAbilityCallbacksIsAdded) {  //没有加入 Fraction
                mAbilityCallbacksIsAdded = true;
                zability.getLifecycle().addObserver(holder.mAbilityCallbacks);
            }
            mNotCommittedAbilityHolders.put(zability, holder); //加入列表
            return holder; //返回
        }
    }
}



